﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Controls.Primitives;
using System.Windows.Markup;

namespace Kokomo
{
	public static class ListViewHelper
	{
		public static bool GetIsSortingEnabled(DependencyObject obj)
		{
			return (bool)obj.GetValue(IsSortingEnabledProperty);
		}

		public static void SetIsSortingEnabled(DependencyObject obj, bool value)
		{
			obj.SetValue(IsSortingEnabledProperty, value);
		}

		// Using a DependencyProperty as the backing store for IsSortingEnabled.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty IsSortingEnabledProperty =
			DependencyProperty.RegisterAttached("IsSortingEnabled", typeof(bool), typeof(ListViewHelper), new UIPropertyMetadata(false, OnIsSortingEnabledChanged));

		private static void OnIsSortingEnabledChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
		{
			UIElement listView = target as UIElement;
			if (listView != null)
			{
				listView.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(OnColumnHeaderClicked));
			}
		}

		private static void OnColumnHeaderClicked(object sender, RoutedEventArgs e)
		{
			ItemsControl itemsControl = sender as ItemsControl;
			if (itemsControl == null) return;

			GridViewColumnHeader header = e.OriginalSource as GridViewColumnHeader;
			if ((header != null) && (header.Column != null))
			{
				string propertyName = GetSortPropertyName(header.Column);
				if ((propertyName != null) && (itemsControl.ItemsSource != null))
				{
					ICollectionView collectionView = CollectionViewSource.GetDefaultView(itemsControl.ItemsSource);
					if (collectionView != null)
					{
						ListSortDirection sortDirection = ListSortDirection.Ascending;
						if (
							(collectionView.SortDescriptions.Count > 0)
							&& (collectionView.SortDescriptions[0].PropertyName == propertyName)
							&& (collectionView.SortDescriptions[0].Direction == ListSortDirection.Ascending)
							)
						{
							sortDirection = ListSortDirection.Descending;
						}
						collectionView.SortDescriptions.Clear();
						collectionView.SortDescriptions.Add(new SortDescription(propertyName, sortDirection));
					}
				}
			}
		}

		public static string GetSortPropertyName(DependencyObject obj)
		{
			return (string)obj.GetValue(SortPropertyNameProperty);
		}

		public static void SetSortPropertyName(DependencyObject obj, string value)
		{
			obj.SetValue(SortPropertyNameProperty, value);
		}

		// Using a DependencyProperty as the backing store for SortPropertyName.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty SortPropertyNameProperty =
			DependencyProperty.RegisterAttached("SortPropertyName", typeof(string), typeof(ListViewHelper), new UIPropertyMetadata(null));



		public static ICommand GetItemActivatedCommand(DependencyObject obj)
		{
			return (ICommand)obj.GetValue(ItemActivatedCommandProperty);
		}

		public static void SetItemActivatedCommand(DependencyObject obj, ICommand value)
		{
			obj.SetValue(ItemActivatedCommandProperty, value);
		}

		// Using a DependencyProperty as the backing store for ItemActivatedCommand.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty ItemActivatedCommandProperty =
			DependencyProperty.RegisterAttached("ItemActivatedCommand", typeof(ICommand), typeof(ListViewHelper), new UIPropertyMetadata(null, OnItemActivatedCommandChanged));

		private static void OnItemActivatedCommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
		{
			Selector selector = target as Selector;
			if (selector == null) return;

			if (e.NewValue != null)
			{
				if (e.OldValue == null)
				{
					selector.KeyDown += new KeyEventHandler(itemsControl_KeyDown);
					selector.MouseDoubleClick += new MouseButtonEventHandler(selector_MouseDoubleClick);
				}
			}
			else
			{
				selector.KeyDown -= new KeyEventHandler(itemsControl_KeyDown);
				selector.MouseDoubleClick -= new MouseButtonEventHandler(selector_MouseDoubleClick);
			}
		}

		static void OnItemActivated(object sender)
		{
			Selector selector = (Selector)sender;
			ICommand itemActivatedCommand = GetItemActivatedCommand((DependencyObject)sender);
			if (itemActivatedCommand != null)
			{
				int selectedIndex = selector.SelectedIndex;
				if (selectedIndex == -1) return;

				DependencyObject container = selector.ItemContainerGenerator.ContainerFromIndex(selectedIndex);
				if (container != null)
				{
					object parameter = container.GetValue(ItemParameterProperty);
					if (parameter == null)
						parameter = selector.ItemContainerGenerator.ItemFromContainer(container);

					if (itemActivatedCommand.CanExecute(parameter))
						itemActivatedCommand.Execute(parameter);
				}
			}
		}

		static void selector_MouseDoubleClick(object sender, MouseButtonEventArgs e)
		{
			OnItemActivated(sender);
			e.Handled = true;
		}

		static void itemsControl_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.Key == Key.Enter)
			{
				OnItemActivated(sender);
				e.Handled = true;
			}
		}




		public static object GetItemParameter(DependencyObject obj)
		{
			return (object)obj.GetValue(ItemParameterProperty);
		}

		public static void SetItemParameter(DependencyObject obj, object value)
		{
			obj.SetValue(ItemParameterProperty, value);
		}

		// Using a DependencyProperty as the backing store for ItemActivatedParameter.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty ItemParameterProperty =
			DependencyProperty.RegisterAttached("ItemParameter", typeof(object), typeof(ListViewHelper), new UIPropertyMetadata(null));


	}
}
